package com.sloan.community.provider;

import com.sloan.community.common.dto.GiteeUserDTO;
import com.sloan.community.exception.CommunityException;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Lazy;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Component;
import org.springframework.web.reactive.function.client.WebClient;
import reactor.core.publisher.Mono;

import java.util.HashMap;
import java.util.Map;

@Component
@Slf4j
@RequiredArgsConstructor(onConstructor_ = {@Lazy})
public class GiteeProvider {

    @Value("${oauth2.gitee.access_token_url}")
    private String accessTokenUrl;

    @Value("${oauth2.gitee.user_info_url}")
    private String userInfoUrl;

    @Value("${oauth2.gitee.client_id}")
    private String clientId;

    @Value("${oauth2.gitee.client_secrets}")
    private String clientSecret;

    @Value("${oauth2.gitee.redirect_url}")
    private String redirectUri;

    private final WebClient webClient;

    public Mono<GiteeUserDTO> fetchUserInfo(String code) {
        Map<String, Object> param = new HashMap<>();
        param.put("client_id", clientId);
        param.put("client_secret", clientSecret);
        param.put("code", code);
        param.put("grant_type", "authorization_code");
        param.put("redirect_uri", redirectUri);
        return webClient.post()
                .uri(accessTokenUrl)
                .contentType(MediaType.APPLICATION_JSON)
                .accept(MediaType.APPLICATION_JSON)
                .bodyValue(param)
                .retrieve()
                .bodyToMono(Map.class)
                .doOnError(err -> log.error("从Gitee获取到accessToken出错:" + err.getMessage()))
                .doOnNext(data -> log.info("从Gitee获取到accessToken数据:{}", data))
                .map(item -> item.get("access_token"))
                .switchIfEmpty(Mono.error(CommunityException.of("Gitee第三方授权登录失败")))
                .onErrorResume(err -> Mono.error(CommunityException.of(err.getMessage())))
                .flatMap(token -> {
                    return webClient.get()
                            .uri(userInfoUrl + "?access_token=" + token)
                            .accept(MediaType.APPLICATION_JSON)
                            .retrieve()
                            .bodyToMono(GiteeUserDTO.class)
                            .doOnError(err -> log.error("从Gitee获取到用户信息出错:" + err.getMessage()));
                })
                .onErrorResume(err -> Mono.error(CommunityException.of("Gitee授权出现问题,请尝试切换其他登录方式登录!")))
                .doOnNext(user -> log.info("从Gitee获取到的用户信息:{}", user));

    }
}
